package com.weilus.service.permission;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.weilus.dao.mapper.*;
import com.weilus.dto.request.PUserDto;
import com.weilus.dto.response.BootstrapTablePage;
import com.weilus.entity.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserService{
	public static final Logger logger = LoggerFactory.getLogger(UserService.class);
	public static final PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();

	@Autowired
	SecurityUserMapper userMapper;
	@Autowired
	SecurityGroupMemberMapper groupMemberMapper;
	@Autowired
	SecurityAuthorityMapper authorityMapper;


	@Autowired(required=false)
	SimpMessagingTemplate template;

	@Transactional
	public Object add(SecurityUser user) {
		user.setCreateTime(new Date());
        user.setEnabled(true);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
		userMapper.insertSelective(user);
		return true;
	}

	@Transactional
	public Object delete(String username){
		SecurityUser user = new SecurityUser();
		user.setEnabled(false);
		user.setUsername(username);
		userMapper.updateByPrimaryKeySelective(user);
		return true;
	}
	@Transactional
	public Object update(SecurityUser user) {
		userMapper.updateByPrimaryKeySelective(user);
		return true;
	}
	public BootstrapTablePage page(PUserDto dto){
		Page<SecurityUser> page = PageHelper.startPage(dto.getPageNumber(),dto.getPageSize());
		SecurityUserExample example = new SecurityUserExample();
		SecurityUserExample.Criteria criteria = example.createCriteria();
		if(!StringUtils.isEmpty(dto.getUsername()))criteria.andUsernameLike(dto.getUsername());
		if(!StringUtils.isEmpty(dto.getRealname()))criteria.andRealnameLike(dto.getRealname());
		if(null != dto.getMax_loginLastime())criteria.andLoginLastimeLessThanOrEqualTo(dto.getMax_loginLastime());
		if(null != dto.getMin_loginLastime())criteria.andLoginLastimeGreaterThanOrEqualTo(dto.getMin_loginLastime());
		if(null != dto.getMax_createTime())criteria.andCreateTimeLessThanOrEqualTo(dto.getMax_createTime());
		if(null != dto.getMin_createTime())criteria.andCreateTimeGreaterThanOrEqualTo(dto.getMin_createTime());
		example.setOrderByClause(" create_time DESC ");
		userMapper.selectByExample(example);
		return new BootstrapTablePage(page);
	}
	@Transactional
	public boolean addUserRight(String username,List<String> authorities) {
		SecurityAuthorityExample authorityExample = new SecurityAuthorityExample();
		authorityExample.createCriteria().andUsernameEqualTo(username);
		authorityMapper.deleteByExample(authorityExample);
		if(!CollectionUtils.isEmpty(authorities)){
			authorities.stream().map(authority->{
				SecurityAuthority auth = new SecurityAuthority();
				auth.setAuthority(authority);
				auth.setUsername(username);
				return auth;
			}).forEach(authorityMapper::insertSelective);
		}
		return true;
	}
	@Transactional
	public boolean addUserRole(String username,List<Integer> roleIds) {
		SecurityGroupMemberExample groupMemberExample = new SecurityGroupMemberExample();
		groupMemberExample.createCriteria().andUsernameEqualTo(username);
		groupMemberMapper.deleteByExample(groupMemberExample);
		if(!CollectionUtils.isEmpty(roleIds)){
			roleIds.stream().map(groupId->{
				SecurityGroupMember groupMember = new SecurityGroupMember();
				groupMember.setGroupId(groupId);
				groupMember.setUsername(username);
				return groupMember;
			}).forEach(groupMemberMapper::insertSelective);
		}
		return true;
	}
	@Transactional
	public boolean updatePwd(String old_pwd,String new_pwd,String username) {
		SecurityUser db_user = userMapper.selectByPrimaryKey(username);
		if(db_user == null) return false;
		if(passwordEncoder.matches(old_pwd,db_user.getPassword())){
			SecurityUser user = new SecurityUser();
			user.setUsername(username);
			user.setPassword(passwordEncoder.encode(new_pwd));
			update(user);
			return true;
		}
		return false;
	}

	public List<Integer> queryUserRole(String username) {
		SecurityGroupMemberExample example = new SecurityGroupMemberExample();
		example.createCriteria().andUsernameEqualTo(username);
		return groupMemberMapper.selectByExample(example)
				.stream().map(SecurityGroupMember::getGroupId)
				.collect(Collectors.toList());
	}

	public List<String> queryUserAuthorities(String username) {
		SecurityAuthorityExample authorityExample = new SecurityAuthorityExample();
		authorityExample.createCriteria().andUsernameEqualTo(username);
		return authorityMapper.selectByExample(authorityExample)
				.stream().map(SecurityAuthority::getAuthority)
				.collect(Collectors.toList());
	}
}
